#include "sgf_lexer.h"

#include <iostream>
#include <fstream>
#include <cstdio>
#include <cstdlib>

SGFLexer::SGFLexer()
{
}

std::vector<SGFToken> SGFLexer::tokenize(std::string filename)
{
    std::vector<SGFToken> tokenList;

    std::cout << "Tokenizing " << filename << std::endl;

    std::string sgf_file = readFile(filename);
    std::cout << sgf_file;

    std::string temp;
    bool text = false;
    for (int i = 0; i < (int)sgf_file.size(); i++)
    {
        if (!text && sgf_file[i] == '(')
            tokenList.push_back(SGFToken(OPEN_PARENS, std::string("(")));
        else if (!text && sgf_file[i] == ')')
            tokenList.push_back(SGFToken(CLOSE_PARENS, std::string(")")));
        else if (!text && sgf_file[i] == ';')
            tokenList.push_back(SGFToken(SEMICOLON, std::string(";")));
        else if (!text && sgf_file[i] == ':')
            tokenList.push_back(SGFToken(COLON, std::string(":")));
        else if (!text && sgf_file[i] == '[' && temp.empty())
        {
            tokenList.push_back(SGFToken(OPEN_SQ_BRACKET, std::string("[")));
            text = true;
        }
        else if (!text && sgf_file[i] == '[' && !temp.empty())
        {
            tokenList.push_back(SGFToken(PROPERTY_ID, std::string(temp)));
            temp.clear();
            tokenList.push_back(SGFToken(OPEN_SQ_BRACKET, std::string("[")));
            text = true;
        }
        else if (sgf_file[i] == ']')
        {
            if (temp.empty())
                tokenList.push_back(SGFToken(NONE, std::string()));
            else
                tokenList.push_back(SGFToken(VALUE, std::string(temp)));
            tokenList.push_back(SGFToken(CLOSE_SQ_BRACKET, std::string("]")));
            temp.clear();
            text = false;
        }
        else
        {
            if (sgf_file[i] == '\\')
            {
                temp += sgf_file[i];
                i++;
            }
            temp += sgf_file[i];
        }
    }

    printTokenList(tokenList);

    return tokenList;
}

std::string SGFLexer::readFile(std::string filename)
{
    std::ifstream inFile(filename.c_str());

    if (!inFile)
    {
        std::cerr << "Error opening file " << filename << "\n";
        exit(EXIT_FAILURE);
    }

    std::string file_contents;
    std::string temp;

    while (!inFile.eof())
    {
        getline(inFile, temp);
        file_contents += temp + "\n";
    }

    inFile.close();

    return file_contents;
}

void SGFLexer::printTokenList(std::vector<SGFToken> list)
{
    std::vector<SGFToken>::iterator it;
    for (it = list.begin(); it != list.end(); it++)
    {
        SGFToken t = *it;
        printf("Type: ");

        switch(t.type)
        {
            case OPEN_PARENS:
                printf("OPEN_PARENS");
                break;
            case CLOSE_PARENS:
                printf("CLOSE_PARENS");
                break;
            case SEMICOLON:
                printf("SEMICOLON");
                break;
            case OPEN_SQ_BRACKET:
                printf("OPEN_SQ_BRACKET");
                break;
            case CLOSE_SQ_BRACKET:
                printf("CLOSE_SQ_BRACKET");
                break;
            case PROPERTY_ID:
                printf("PROPERTY_ID");
                break;
            case NONE:
                printf("NONE");
                break;
            case VALUE:
                printf("VALUE");
                break;
            default:
                printf(" ");
        }

        printf("; Value: %s\n", t.value.c_str());
    }
}
